package model.entity.container;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Iterator;

import model.exceptions.InvalidNameException;
import model.exceptions.NullContainerException;

import org.junit.Test;

import common.Result;

public class StorageUnitTest
{
  @Test
  public void basicTest() throws InvalidNameException
  {
    StorageUnit basement = new StorageUnit("Basement");
    assertEquals("Basement", basement.getName());
  }

  @Test
  public void invalidName()
  {
    try
    {
      new StorageUnit("");
      fail();
    }
    catch (InvalidNameException e)
    {
      // this should occur
    }
  }

  @Test
  public void validateAddProductGroupTest() throws InvalidNameException, NullContainerException
  {
    StorageUnit unit = new StorageUnit("unit");
    ProductGroup group = new ProductGroup("group", unit, 1);

    Result result = unit.validateAddProductGroup(group);
    assertTrue(result.getStatus());

    unit.addProductGroup(group);

    ProductGroup g2 = new ProductGroup("group", unit, 1);
    result = unit.validateAddProductGroup(g2);
    assertFalse(result.getStatus());

    g2 = new ProductGroup("g2", unit, 1);
    result = unit.validateAddProductGroup(group);
    assertTrue(result.getStatus());
  }

  @Test
  public void addProductGroupTest() throws InvalidNameException, NullContainerException
  {
    StorageUnit unit = new StorageUnit("unit");

    // add new product group
    ProductGroup g1 = new ProductGroup("group", unit, 1);
    Result result = unit.addProductGroup(g1);
    assertTrue(result.getStatus());

    Iterator<ProductGroup> itr = unit.getProductGroups();
    assertTrue(itr.hasNext());
    assertEquals(g1, itr.next());
    assertFalse(itr.hasNext());

    // try to add a product group that is already added
    result = unit.addProductGroup(g1);
    assertFalse(result.getStatus());

    itr = unit.getProductGroups();
    assertTrue(itr.hasNext());
    assertEquals(g1, itr.next());
    assertFalse(itr.hasNext());

    // try to add a product group with the same name as the one already added
    ProductGroup g2 = new ProductGroup("group", unit, 1);
    result = unit.addProductGroup(g2);
    assertFalse(result.getStatus());

    itr = unit.getProductGroups();
    assertTrue(itr.hasNext());
    assertEquals(g1, itr.next());
    assertFalse(itr.hasNext());

    // try to add a new, unique product group
    g2 = new ProductGroup("new group", unit, 1);
    result = unit.addProductGroup(g2);
    assertTrue(result.getStatus());

    itr = unit.getProductGroups();
    assertTrue(itr.hasNext());
    ProductGroup first = itr.next();
    assertTrue(first.equals(g1) || first.equals(g2));
    assertTrue(itr.hasNext());
    ProductGroup second = itr.next();
    assertTrue(second.equals(g1) || second.equals(g2));
    assertFalse(first.equals(second));
    assertFalse(itr.hasNext());
  }
}
